
package com.naza.rpc.netty;

import com.google.common.reflect.AbstractInvocationHandler;

import java.lang.reflect.Method;
import java.util.UUID;

import com.naza.rpc.consumer.balance.manage.ClientManage;
import com.naza.rpc.core.MessageCallBack;
import com.naza.rpc.model.LoadBalance;
import com.naza.rpc.model.LoadBalanceImpl;
import com.naza.rpc.model.RpcRequest;
import com.naza.rpc.model.ServiceInstance;
import com.naza.rpc.util.PropertiesUtil;

/**
 * RPC客户端消息处理  ,代理类的拦截器
 * 
 * @author yl
 */
public class RpcSendProxy<T> extends AbstractInvocationHandler {

    private ClientManage clientManage = ClientManage.INSTANCE;

    /**
     * 拦截客户端代理类的所有方法
     * 
     * @see com.google.common.reflect.AbstractInvocationHandler#handleInvocation(java.lang.Object,
     *      java.lang.reflect.Method, java.lang.Object[])
     */

    @Override
    public Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
        //包装请求
        RpcRequest request = new RpcRequest();
        request.setMessageId(UUID.randomUUID().toString());
        request.setClassName(method.getDeclaringClass().getName());
        request.setMethodName(method.getName());
        request.setTypeParameters(method.getParameterTypes());
        request.setParametersVal(args);
        ServiceInstance serviceInstance = clientManage.selectClient(method.getDeclaringClass().getName(), getLoadBalanceRoute(PropertiesUtil.getINSTANCE().getValue("loadbalanceRoute")));
        if(null == serviceInstance){
            return null;
        }
        RpcSendHandler handler = RpcServerLoader.getInstance().getMessageSendHandler(serviceInstance.getIp()+":"+serviceInstance.getPort());
        // 客户端将请求发向服务端，结果异步回调
        MessageCallBack callBack = handler.sendRequest(request);
        return callBack.start();
    }

    private LoadBalance getLoadBalanceRoute(String route){
        if("round".equals(route)){
            return LoadBalanceImpl.DEFAULT;
        }
        else if("random".equals(route)){
            return new LoadBalanceImpl(LoadBalance.Type.ROUND_ROBIN);
        }
        return LoadBalanceImpl.DEFAULT;
    }
}
